﻿using System;
using System.Linq;
using log4net;
using log4net.Appender;
using log4net.Core;

namespace MassPokerTool.Infrastructure.Logging
{
    /// <summary>
    /// Log helper class.
    /// </summary>
    public static class LogHelper
    {
        /// <summary>
        /// Sets log level for specified appender.
        /// </summary>
        /// <param name="appenderType"></param>
        /// <param name="level"></param>
        public static void SetAppenderLogLevel(Type appenderType, LogLevel level)
        {
            if (typeof(AppenderSkeleton).IsAssignableFrom(appenderType))
            {
                var appender =  LogManager.GetRepository().GetAppenders().FirstOrDefault(a => a.Name == appenderType.Name);
                if (appender != null)
                {
                    var castedAppender = (AppenderSkeleton) Convert.ChangeType(appender, appenderType);
                    castedAppender.Threshold = level.MapToLog4NetLevel();
                    castedAppender.ActivateOptions();
                }
            }
        } 

        /// <summary>
        /// Sets output log file.
        /// </summary>
        /// <param name="logfile"></param>
        public static void SetLogFile(string logfile)
        {
            var fileAppender =
                LogManager.GetRepository().GetAppenders()
                    .FirstOrDefault(a => a is FileAppender);

            if (fileAppender != null)
            {
                var castedAppender = (FileAppender) fileAppender;
                castedAppender.File = logfile;
                castedAppender.ActivateOptions();
            }
        }

        /// <summary>
        /// Gets the current application log level.
        /// </summary>
        /// <returns></returns>
        public static LogLevel GetCurrentLevel()
        {
            return LogManager.GetRepository().Threshold.MapToLogLevel();
        }

        /// <summary>
        /// Sets the current application log level.
        /// </summary>
        /// <param name="level"></param>
        public static void SetCurrentLevel(LogLevel level)
        {
            LogManager.GetRepository().Threshold = level.MapToLog4NetLevel();
        }

        /// <summary>
        /// Maps log4net log level to custom one.
        /// </summary>
        /// <param name="level"></param>
        /// <returns></returns>
        public static Level MapToLog4NetLevel(this LogLevel level)
        {
            switch (level)
            {
                case LogLevel.Error:
                    return Level.Error;
                case LogLevel.Info:
                    return Level.Info;
                case LogLevel.Off:
                    return Level.Off;
                case LogLevel.Warn:
                    return Level.Warn;
                case LogLevel.Debug:
                    return Level.Debug;
                default:
                    throw new ApplicationException(string.Format("The log level '{0}' is unknown", level.ToString()));
            }
        }

        /// <summary>
        /// Maps custom log level to log4net level.
        /// </summary>
        /// <param name="level"></param>
        /// <returns></returns>
        public static LogLevel MapToLogLevel(this Level level)
        {
            if (level == Level.Error)
                return LogLevel.Error;
            if (level == Level.Info)
                return LogLevel.Info;
            if (level == Level.Off)
                return LogLevel.Off;
            if (level == Level.Warn)
                return LogLevel.Warn;
            if (level == Level.Debug)
                return LogLevel.Debug;
            throw new ApplicationException(string.Format("The level '{0}' is unknown", level.ToString()));
        }
    }
}
